package com.tanhua.manage.service;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.unit.DataUnit;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.additional.query.impl.QueryChainWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sun.corba.se.impl.orbutil.ObjectStreamClassUtil_1_3;
import com.tanhua.manage.domain.AnalysisByDay;
import com.tanhua.manage.mapper.AdminMapper;
import com.tanhua.manage.mapper.AnalysisByDayMapper;
import com.tanhua.manage.mapper.LogMapper;
import com.tanhua.manage.utils.ComputeUtil;
import com.tanhua.manage.vo.AnalysisSummaryVo;
import com.tanhua.manage.vo.AnalysisUsersVo;
import com.tanhua.manage.vo.DataPointVo;
import org.apache.commons.collections.CollectionUtils;
import org.apache.http.client.utils.DateUtils;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import javax.management.Query;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

@Service
public class AnalysisService extends ServiceImpl<AnalysisByDayMapper, AnalysisByDay> {

    @Autowired
    private LogMapper logMapper;
    @Autowired
    private AnalysisByDayMapper analysisByDayMapper;

    /**
     * 概要统计信息
     *
     * @return
     */
    public AnalysisSummaryVo queryAnalysisSummary() {
        AnalysisSummaryVo analysisSummaryVo = new AnalysisSummaryVo();
        Date date = new Date();
        //记录当前时间
        DateTime today = DateUtil.offsetDay(date, 0);
        //记录昨天时间
        DateTime yesterday = DateUtil.offsetDay(date, -1);
        analysisSummaryVo.setCumulativeUsers(queryCumulativeUsers());//累计用户数
        //封装过去30天活跃用户数
        analysisSummaryVo.setActivePassMonth
                (queryUserCount(today, -30, "num_active"));
        //封装过去7天活跃用户
        analysisSummaryVo.setActivePassWeek
                (queryUserCount(today, -7, "num_active"));
        //查询今日新增数量
        Long todayRegisterNum = queryUserCount(today, 0, "num_registered");
        //封装今日新增用户数量
        analysisSummaryVo.setNewUsersToday(todayRegisterNum);
        //查询昨日新增数量
        Long yesterdayRegisterNum = queryUserCount(yesterday, 0, "num_registered");
        //查询并封装涨跌率
        analysisSummaryVo.setNewUsersTodayRate(ComputeUtil.computeRate(todayRegisterNum, yesterdayRegisterNum));
        //获取今日登录次数
        Long todayLoginNum = queryUserCount(today, 0, "num_login");
        //获取昨日登录次数
        Long num_login = queryUserCount(yesterday, 0, "num_login");
        //封装今日登录次数
        analysisSummaryVo.setLoginTimesToday(todayLoginNum);
        //      今日登录次数涨跌率，单位百分数，正数为涨，负数为跌
        analysisSummaryVo.setLoginTimesTodayRate(ComputeUtil.computeRate(todayLoginNum, num_login));
        //获取今日活跃次数
        Long today_active = queryUserCount(today, 0, "num_active");
        //获取昨日活跃次数
        Long yesterday_active = queryUserCount(yesterday, 0, "num_active");
        //今日活跃用户数量
        analysisSummaryVo.setActiveUsersToday(today_active);
        //      今日活跃用户涨跌率，单位百分数，正数为涨，负数为跌
        analysisSummaryVo.setActiveUsersTodayRate(ComputeUtil.computeRate(today_active, yesterday_active));
        return analysisSummaryVo;
    }

    /**
     * 累计用户数
     */
    public Long queryCumulativeUsers() {
        //创建条件构造器
        QueryWrapper<AnalysisByDay> queryWrapper = new QueryWrapper<>();
        //创建查询条件
        QueryWrapper<AnalysisByDay> select = queryWrapper.select("SUM(num_registered) as numActive");
        AnalysisByDay analysisByDay =getOne(select);
        //取出总记录数 （已经封装到指定的属性字段
        Integer sumRegister = analysisByDay.getNumActive();
        //返回结果
        return sumRegister.longValue();
    }

    //SELECT SUM(num_registered) FROM tb_analysis_by_day WHERE record_date <= NEW DATE AND record_date>=?
    //抽取统计的公共方法
    public Long queryUserCount(DateTime today, int offset, String columnName) {
        //创建条件构造器
        QueryWrapper<AnalysisByDay> queryWrapper = new QueryWrapper<>();
        //设置查询条件
        queryWrapper.select("SUM(" + columnName + ") as numActive")
                .ge("record_date", DateUtil.offsetDay(today,offset).toDateStr())
                .le("record_date", today.toDateStr());
        //查询
        AnalysisByDay analysisByDay = getOne(queryWrapper);
        if (ObjectUtils.isEmpty(analysisByDay)) {
            analysisByDay = new AnalysisByDay();
            analysisByDay.setNumActive(0);
        }
        //返回数量
        return analysisByDay.getNumActive().longValue();
    }

    /**
     * 新增、活跃用户、次日留存率
     */
    public AnalysisUsersVo statisticalRetentionRate(Long sd, Long ed, Long type) {

        //将日期转换成DataTime类型
        DateTime startDate = DateUtil.date(sd);
        DateTime endDate = DateUtil.date(ed);
        //时间设置一年前
        DateTime offsetStartDate = DateUtil.offset(startDate, DateField.YEAR, -1);
        DateTime offsetEndDate = DateUtil.offset(endDate, DateField.YEAR, -1);
        AnalysisUsersVo analysisUsersVo = new AnalysisUsersVo();
        //调用方法
        analysisUsersVo.setThisYear(queryDataPointVo(startDate, endDate, type));
        analysisUsersVo.setLastYear(queryDataPointVo(offsetStartDate, offsetEndDate, type));
        //返回数据
        return analysisUsersVo;
    }

    /**
     * 传入参数 返回结果
     */
    public List<DataPointVo> queryDataPointVo(DateTime sd, DateTime ed, Long type) {
        //转换日期格式
        String startDate = sd.toDateStr();
        String endDate = ed.toDateStr();
        //动态切换查询的表名
        String column = null;
        if (StringUtils.isEmpty(type)) {
            type = 0l;
        }
        switch (type.intValue()) {
            case 101:
                column = "num_registered";
                break;
            case 102:
                column = "num_active";
                break;
            case 103:
                column = "num_retention1d";
                break;
            default:
                column = "num_active";
                break;
        }
        //根据条件查询
        QueryWrapper<AnalysisByDay> byDayQueryWrapper = new QueryWrapper<AnalysisByDay>()
                .select("record_date , " + column + " as num_active")
                .ge("record_date", startDate)
                .le("record_date", endDate);
        List<AnalysisByDay> analysisByDayList = list(byDayQueryWrapper);

        //遍历analysisByDayList集合
        ArrayList<DataPointVo> dataPointVos = new ArrayList<>();
        for (AnalysisByDay analysisByDay : analysisByDayList) {
            DataPointVo dataPointVo = new DataPointVo();
            dataPointVo.setTitle(analysisByDay.getRecordDate().toString());
            dataPointVo.setAmount(analysisByDay.getNumActive().longValue());
            dataPointVos.add(dataPointVo);
        }
        //返回
        return dataPointVos;
    }

    /**
     * 统计日志信息到概要信息表
     */
    public void timedStatisticsLogInformation() {
        //将当前的时间转换成yyyy-MM-dd字符串格式
        String todayDate = ComputeUtil.offsetDay(new Date(), 0);
        String yesterdayTime = ComputeUtil.offsetDay(new Date(), -1);
        //使用工具类创建出昨天的日期格式
        //创建一个Date对象 表示当前时间
        Date currentDate = new Date();
        //统计log表中，今日的注册人数
        String type = "02";
        Integer num_registered = logMapper.queryNumByTimeAndDate(type, todayDate);
        //统计log表中，今日的登录人数
        type = "01";
        Integer num_login = logMapper.queryNumByTimeAndDate(type, todayDate);
        //统计log表中，今日的活跃人数
        Integer num_active = logMapper.queryNumActiveByTimeAndDate(todayDate);
        //统计log表中，次日留存用户
        Integer num_retention1d = logMapper.queryNumRetentionByTimeAndDate(yesterdayTime, todayDate);
        //查询tb_analysis_by_day表中是否存在记录 如果存在那么就插入 如果不存在那么就更新语句
        QueryWrapper<AnalysisByDay> byDayQueryWrapper = new QueryWrapper<AnalysisByDay>()
                .eq("record_date",ComputeUtil.offsetDay(new Date(),0));
        AnalysisByDay analysisByDay = analysisByDayMapper.selectOne(byDayQueryWrapper);
        if(ObjectUtils.isEmpty(analysisByDay)){
            //设置预插入的数据
            analysisByDay.setNumRegistered(num_registered);//今日的注册人数
            analysisByDay.setNumLogin(num_login);//今日的登录人数
            analysisByDay.setNumActive(num_active);//今日的活跃人数
            analysisByDay.setNumRetention1d(num_retention1d);//次日留存用户
            analysisByDay.setRecordDate(currentDate);//日志创建时间
            analysisByDayMapper.insert(analysisByDay);//插入字段
        }
        else {
            analysisByDay.setId(analysisByDay.getId());//非空的时候根据主键更新字段
            analysisByDay.setNumRegistered(num_registered);//今日的注册人数
            analysisByDay.setNumLogin(num_login);//今日的登录人数
            analysisByDay.setNumActive(num_active);//今日的活跃人数
            analysisByDay.setNumRetention1d(num_retention1d);//次日留存用户
            analysisByDayMapper.updateById(analysisByDay);//根据Id修改
        }


    }
}
